package top.dbpanda.cmsjpa.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.dbpanda.cmsjpa.entity.UserEntity;
import top.dbpanda.cmsjpa.model.dto.AddUserDTO;
import top.dbpanda.cmsjpa.repository.UserRepository;
import top.dbpanda.cmsjpa.service.UserService;

import java.util.concurrent.locks.ReentrantLock;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;

    private final ReentrantLock lock = new ReentrantLock();

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserEntity add(AddUserDTO addUser) {
        UserEntity userEntity = BeanUtil.copyProperties(addUser, UserEntity.class);
        userEntity.setSalt(RandomUtil.randomString(10));
        long count = userRepository.count() + 1;
        if (count > 2) {
            throw new RuntimeException("大于2");
        }
        userEntity.setAccount(userEntity.getAccount() + count);
        userEntity.setNickName(userEntity.getNickName() + count);
        userRepository.save(userEntity);
        return userEntity;
    }

    @Override
    public UserEntity testLock(AddUserDTO addUser) {
        lock.lock();
        String currentThreadName = Thread.currentThread().getName();
        log.info("当前获取锁的线程:{}", currentThreadName);
        UserEntity userEntity;
        try {
            userEntity = add(addUser);
        } finally {
            lock.unlock();
            log.info("当前释放锁的线程:{}", currentThreadName);
        }
        return userEntity;
    }

    @Override
    public UserEntity testSynchronized(AddUserDTO addUser) {
        String currentThreadName = Thread.currentThread().getName();
        log.info("当前获取锁的线程:{}", currentThreadName);
        UserEntity userEntity;
        synchronized (this) {
            userEntity = add(addUser);
        }
        return userEntity;
    }
}
